package com.explore.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.explore.demo.VO.DeliveryLogVO;
import com.explore.demo.common.ResultCode;
import com.explore.demo.common.ServerResponse;
import com.explore.demo.config.JwtConfig;
import com.explore.demo.mapper.*;
import com.explore.demo.pojo.*;
import com.explore.demo.service.HumanSourceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.aspectj.apache.bcel.classfile.ConstantValue;
import org.intellij.lang.annotations.RegExp;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.rmi.ServerError;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author gaolainan
 * @since 2021-04-18
 */
@Service
public class HumanSourceServiceImpl  extends ServiceImpl<HumanSourceMapper, HumanSource>implements HumanSourceService{

    /**
     * 打印日志文件
     */
    private final Logger logger = LoggerFactory.getLogger(HumanSourceServiceImpl.class);

    @Resource
    private HumanSourceMapper humanSourceMapper;

    @Resource
    private RecruitmentMapper recruitmentMapper;

    @Resource
    private DeliveryLogMapper deliveryLogMapper;

    @Resource
    private CompanyMapper companyMapper;

    @Resource
    private JwtConfig jwtConfig;

    @Resource
    private UserMapper userMapper;

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private RowViewMapper rowViewMapper;

    @Resource
    private CompanyCategoryMapper companyCategoryMapper;

    @Override
    public ServerResponse addHumanSource(HumanSource humanSource)
    {
        if (humanSource == null){
            return ServerResponse.createBySuccessMessage(ResultCode.HUMAN_IS_NULL.getDescription(),
                                                         ResultCode.HUMAN_IS_NULL.getCode(),
                                                         null);
        }
        return humanSourceMapper.insert(humanSource) != 0?
               ServerResponse.createBySuccessMessage(ResultCode.SUCCESS.getDescription(),
                                                     ResultCode.SUCCESS.getCode(),
                                                     null):
               ServerResponse.createBySuccessMessage(ResultCode.HUMAN_INSERT_FAIL.getDescription(),
                                                     ResultCode.HUMAN_INSERT_FAIL.getCode(),
                                                     null);
    }

    @Override
    public ServerResponse deleteByRealName(String realName)
    {
        if (realName == null){
            return ServerResponse.createBySuccessMessage(ResultCode.HUMAN_NAME_IS_NULL.getDescription(),
                                                         ResultCode.HUMAN_NAME_IS_NULL.getCode(),
                                                         null);
        }
        QueryWrapper<HumanSource> wrapper = new QueryWrapper<>();
        wrapper.eq("real_name",realName);
        HumanSource humanSource = humanSourceMapper.selectOne(wrapper);
        UpdateWrapper<HumanSource> updateWrapper = new UpdateWrapper<>();
        updateWrapper
                .set("deleted",1);
        return humanSourceMapper.update(humanSource,updateWrapper) != 0?
               ServerResponse.createBySuccessMessage(ResultCode.SUCCESS.getDescription(),
                                                     ResultCode.SUCCESS.getCode(),
                                                     null):
               ServerResponse.createBySuccessMessage(ResultCode.HUMAN_DELETE_FAIL.getDescription(),
                                                     ResultCode.HUMAN_DELETE_FAIL.getCode(),
                                                     null);
    }

    @Override
    public ServerResponse queryAll()
    {
        QueryWrapper<HumanSource> wrapper = new QueryWrapper<>();
        wrapper
                .ge("id",1);
        return ServerResponse.createBySuccessMessage(ResultCode.SUCCESS.getDescription(),
                                                     ResultCode.SUCCESS.getCode(),
                                                     humanSourceMapper.selectList(wrapper));
    }

    @Override
    public ServerResponse queryByRealName(String realName)
    {
        if (realName == null){
            return ServerResponse.createBySuccessMessage(ResultCode.HUMAN_NAME_IS_NULL.getDescription(),
                                                         ResultCode.HUMAN_NAME_IS_NULL.getCode(),
                                                         null);
        }
        QueryWrapper<HumanSource> wrapper = new QueryWrapper<>();
        wrapper
                .eq("real_name",realName);
        return ServerResponse.createBySuccessMessage(ResultCode.SUCCESS.getDescription(),
                                                     ResultCode.SUCCESS.getCode(),
                                                     humanSourceMapper.selectList(wrapper));
    }

    @Override
    public ServerResponse updateHumanSource(HumanSource humanSource)
    {
        if (humanSource == null){
            return ServerResponse.createBySuccessMessage(ResultCode.HUMAN_IS_NULL.getDescription(),
                                                         ResultCode.HUMAN_IS_NULL.getCode(),
                                                         null);
        }
        return humanSourceMapper.updateById(humanSource) != 0?
               ServerResponse.createBySuccessMessage(ResultCode.SUCCESS.getDescription(),
                                                     ResultCode.SUCCESS.getCode(),
                                                     null):
               ServerResponse.createBySuccessMessage(ResultCode.UPDATE_FAIL.getDescription(),
                                                     ResultCode.UPDATE_FAIL.getCode(),
                                                     null);
    }

    @Override
    public ServerResponse showOwnRecruitment(HttpServletRequest request)
    {
        String token =  request.getHeader(jwtConfig.getHeader());
        String phone = jwtConfig.getUsernameFromToken(token);
        HumanSource humanSource = humanSourceMapper.selectOne(new QueryWrapper<HumanSource>().eq("phone", phone));
        List<Recruitment> recruitment = recruitmentMapper
                .selectList(new QueryWrapper<Recruitment>().eq("human_source_id", humanSource.getId()));
        return ServerResponse.createBySuccessMessage("success", 200, recruitment);
    }

    @Override
    public ServerResponse humanLogin(@NotNull String account,@NotNull String password)
    {
        QueryWrapper<HumanSource> humanSourceQueryWrapper = new QueryWrapper<>();
        humanSourceQueryWrapper.eq("phone", account);
        HumanSource humanSource = humanSourceMapper.selectOne(humanSourceQueryWrapper);
        if (humanSource == null){
            return ServerResponse.createBySuccessMessage("用户不存在", 2000,null);
        }
        if (!humanSource.getPassword().equals(password)){
            return ServerResponse.createBySuccessMessage("密码错误", 2001,null);
        }
        String token = jwtConfig.createToken(account);
        logger.info("token生成成功"+token);
        HashMap<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("humanSource", humanSource);
        return ServerResponse.createBySuccessMessage("success", 200, map);
    }

    @Override
    public ServerResponse getDeliveryLogs(HttpServletRequest request)
    {
        String token =  request.getHeader(jwtConfig.getHeader());
        String phone = jwtConfig.getUsernameFromToken(token);
        HumanSource humanSource = humanSourceMapper.selectOne(new QueryWrapper<HumanSource>().eq("phone", phone));
        List<DeliveryLog> list = deliveryLogMapper.getDeliveryByHumanSourceId(humanSource.getId());
        List<DeliveryLogVO> res = new ArrayList<>();
        for(DeliveryLog tmp : list){
            DeliveryLogVO deliveryLogVO = new DeliveryLogVO();
            Recruitment recruitment = recruitmentMapper.selectOne(new QueryWrapper<Recruitment>().eq("id", tmp.getRecruitId()));
            Company company = companyMapper.selectOne(new QueryWrapper<Company>().eq("id", recruitment.getCompanyId()));
            User user = userMapper.selectOne(new QueryWrapper<User>().eq("id", tmp.getUserId()));
            deliveryLogVO.setId(tmp.getId())
                         .setCompanyName(company.getCompanyName())
                         .setRecruitName(recruitment.getTitle())
                         .setCreateTime(tmp.getCreateTime())
                         .setGender(user.getGender())
                         .setExperience(user.getEducation())
                         .setUserName(user.getRealName())
                         .setPath(tmp.getFilePath());
            res.add(deliveryLogVO);
        }
        return ServerResponse.createBySuccessMessage("success", 200, res);
    }

    @Override
    public ServerResponse downloadResume(Integer id ,HttpServletResponse response) throws IOException
    {
        DeliveryLog log = deliveryLogMapper.selectOne(new QueryWrapper<DeliveryLog>().eq("id", id));
        String filePath = log.getFilePath();
        File file = new File(filePath);
        if (file == null){
            return ServerResponse.createBySuccessMessage("the file is not exist!", 2000,null);
        }
        // 下载文件
        FileInputStream fileInputStream = new FileInputStream(file);
        //设置Http响应头告诉浏览器下载这个附件,下载的文件名也是在这里设置的
        response.setHeader("Content-Disposition", "attachment;Filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
        OutputStream outputStream = response.getOutputStream();
        byte[] bytes = new byte[2048];
        int len = 0;
        while ((len = fileInputStream.read(bytes))>0){
            outputStream.write(bytes,0,len);
        }
        fileInputStream.close();
        outputStream.close();
        return ServerResponse.createBySuccessMessage("success", 200, null);
    }

    @Override
    public ServerResponse listRecruitment(HttpServletRequest request)
    {
        String token =  request.getHeader(jwtConfig.getHeader());
        String phone = jwtConfig.getUsernameFromToken(token);
        HumanSource humanSource = humanSourceMapper.selectOne(new QueryWrapper<HumanSource>().eq("phone", phone));
        List<Recruitment> list = recruitmentMapper
                .selectList(new QueryWrapper<Recruitment>().eq("human_source_id", humanSource.getId()));
        List<HashMap<String, Object>> res = new ArrayList<>();
        for (Recruitment tmp : list){
            HashMap<String, Object> map = new HashMap<>();
            map.put("title", tmp.getTitle());
            Company company = companyMapper.selectOne(new QueryWrapper<Company>().eq("id", tmp.getCompanyId()));
            map.put("companyName", company.getCompanyName());
            RowView row = rowViewMapper.selectOne(new QueryWrapper<RowView>().eq("recruit_id", tmp.getId()));
            map.put("views", row.getReadNum());
            map.put("recruit_id", tmp.getId());
            map.put("stars", row.getCollectNum());
            map.put("createTime", tmp.getCreateTime());
            map.put("name", humanSource.getRealName());
            res.add(map);
        }
        return ServerResponse.createBySuccessMessage("success", 200 ,res);
    }

    @Override
    public ServerResponse searchByRecruitmentName(String info, HttpServletRequest request)
    {
        String token =  request.getHeader(jwtConfig.getHeader());
        String phone = jwtConfig.getUsernameFromToken(token);
        HumanSource humanSource = humanSourceMapper.selectOne(new QueryWrapper<HumanSource>().eq("phone", phone));
        List<Recruitment> list = recruitmentMapper
                .selectList(new QueryWrapper<Recruitment>().eq("human_source_id", humanSource.getId()).like("title", info));
        List<HashMap<String, Object>> res = new ArrayList<>();
        for (Recruitment tmp : list){
            HashMap<String, Object> map = new HashMap<>();
            map.put("title", tmp.getTitle());
            Company company = companyMapper.selectOne(new QueryWrapper<Company>().eq("id", tmp.getCompanyId()));
            map.put("companyName", company.getCompanyName());
            RowView row = rowViewMapper.selectOne(new QueryWrapper<RowView>().eq("recruit_id", tmp.getId()));
            map.put("views", row.getReadNum());
            map.put("stars", row.getCollectNum());
            map.put("createTime", tmp.getCreateTime());
            map.put("name", humanSource.getRealName());
            res.add(map);
        }
        return ServerResponse.createBySuccessMessage("success", 200 ,res);
    }

    @Override
    public ServerResponse searchDeliveryLogByUserName(String info, HttpServletRequest request)
    {
        String token =  request.getHeader(jwtConfig.getHeader());
        String phone = jwtConfig.getUsernameFromToken(token);
        HumanSource humanSource = humanSourceMapper.selectOne(new QueryWrapper<HumanSource>().eq("phone", phone));
        List<DeliveryLog> logs = deliveryLogMapper.getDeliveryByHumanSourceId(humanSource.getId());
        List<User> userList = userMapper.selectList(new QueryWrapper<User>().like("real_name", info));
        List<Integer> idList = new ArrayList<>();
        userList.forEach(s -> idList.add(s.getId()));
        List<DeliveryLog> res= new ArrayList<>();
        logs.stream().filter(s -> idList.contains(s.getUserId())).forEach(res :: add);
        List<DeliveryLogVO> result = new ArrayList<>();
        for (DeliveryLog tmp : res){
            DeliveryLogVO deliveryLogVO = new DeliveryLogVO();
            Recruitment recruitment = recruitmentMapper.selectOne(new QueryWrapper<Recruitment>().eq("id", tmp.getRecruitId()));
            Company company = companyMapper.selectOne(new QueryWrapper<Company>().eq("id", recruitment.getCompanyId()));
            User user = userMapper.selectOne(new QueryWrapper<User>().eq("id", tmp.getUserId()));
            deliveryLogVO.setId(tmp.getId())
                         .setCompanyName(company.getCompanyName())
                         .setRecruitName(recruitment.getTitle())
                         .setCreateTime(tmp.getCreateTime())
                         .setGender(user.getGender())
                         .setExperience(user.getEducation())
                         .setUserName(user.getRealName())
                         .setPath(tmp.getFilePath());
            result.add(deliveryLogVO);
        }
        return ServerResponse.createBySuccessMessage("success", 200, result);
    }

    @Override
    public ServerResponse getOwnCompanyInfo(HttpServletRequest request)
    {
        String token =  request.getHeader(jwtConfig.getHeader());
        String phone = jwtConfig.getUsernameFromToken(token);
        HumanSource humanSource = humanSourceMapper.selectOne(new QueryWrapper<HumanSource>().eq("phone", phone));
        Company company = companyMapper.selectOne(new QueryWrapper<Company>().eq("id", humanSource.getDepartmentId()));
        ConcurrentHashMap<String, Object> map = new ConcurrentHashMap<>(2);
        List<CompanyCategory> category = companyCategoryMapper
                .selectList(new QueryWrapper<CompanyCategory>().eq("company_id", company.getId()));
        List<String> companyCategory = new ArrayList<>();
        category.forEach(tmp -> companyCategory.add(categoryMapper.selectOne(new QueryWrapper<Category>().eq("id", tmp.getCategoryId())).getCategoryName()));
        map.put("company", company);
        map.put("company_category", companyCategory);
        return ServerResponse.createBySuccessMessage("success", 200, map);
    }

    @Override
    public ServerResponse register(String account, String password, String realName, HttpServletRequest request)
    {
        List<HumanSource> list = humanSourceMapper.selectList(new QueryWrapper<HumanSource>().eq("phone", account));
        if (list.size() != 0){
            return ServerResponse.createBySuccessMessage("account is already exists", 2000, null);
        }
        HumanSource humanSource = new HumanSource();
        humanSource.setPhone(account).setPassword(password).setRealName(realName);
        return humanSourceMapper.insert(humanSource) == 0 ?
               ServerResponse.createBySuccessMessage("fail", 2000, null):
               ServerResponse.createBySuccessMessage("success", 200, null);
    }
}
